import log from 'electron-log'
import fetch from 'node-fetch'

/**
 * Umi-OCR 服务
 * 通过 HTTP 接口调用 Umi-OCR 进行 OCR 识别
 * 
 * 文档：https://github.com/hiroi-sora/Umi-OCR
 */
export class UmiOCRService {
  private apiUrl: string
  private timeout: number
  private language: string

  constructor(config: {
    apiUrl: string
    language?: string
    timeout?: number
  }) {
    this.apiUrl = config.apiUrl.replace(/\/$/, '') // 移除末尾的斜杠
    this.language = config.language || 'chi_sim'
    this.timeout = config.timeout || 10000

    log.info('[Umi-OCR] 服务初始化完成', {
      apiUrl: this.apiUrl,
      language: this.language,
      timeout: this.timeout,
    })
  }

  /**
   * 测试 Umi-OCR 服务连接
   */
  async testConnection(): Promise<{ success: boolean; error?: string }> {
    try {
      log.info('[Umi-OCR] 测试服务连接...')
      
      // 尝试访问根路径或状态接口
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), 5000)
      
      const response = await fetch(`${this.apiUrl}/api/status`, {
        signal: controller.signal,
      })
      
      clearTimeout(timeoutId)

      if (response.ok) {
        log.info('[Umi-OCR] 服务连接成功')
        return { success: true }
      }

      // 如果状态接口不存在（404），也认为服务可用
      if (response.status === 404) {
        log.warn('[Umi-OCR] 状态接口不存在，但服务可访问')
        return { success: true }
      }

      return {
        success: false,
        error: `服务返回状态码: ${response.status}`,
      }
    } catch (error: any) {
      log.error('[Umi-OCR] 服务连接失败:', error.message)
      
      let errorMessage = '连接失败'
      if (error.name === 'AbortError') {
        errorMessage = '连接超时，请确保 Umi-OCR 服务已启动'
      } else if (error.code === 'ECONNREFUSED') {
        errorMessage = 'Umi-OCR 服务连接失败，请确保服务已启动'
      } else {
        errorMessage = error.message || '连接失败'
      }
      
      return {
        success: false,
        error: errorMessage,
      }
    }
  }

  /**
   * 执行 OCR 识别
   * @param imageBase64 图片的 base64 编码（支持带 data:image/png;base64, 前缀或纯 base64）
   * @returns OCR 识别结果文本
   */
  async recognize(imageBase64: string): Promise<{
    success: boolean
    text?: string
    error?: string
    details?: any
  }> {
    try {
      log.info('[Umi-OCR] 开始 OCR 识别...')
      const startTime = Date.now()

      // 处理 base64 字符串（移除 data:image/png;base64, 前缀）
      let base64Data = imageBase64
      if (imageBase64.includes(',')) {
        base64Data = imageBase64.split(',')[1]
      }

      // 调用 Umi-OCR API
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), this.timeout)
      
      const response = await fetch(`${this.apiUrl}/api/ocr`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          base64: base64Data,
          options: {
            language: this.language,
          },
        }),
        signal: controller.signal,
      })
      
      clearTimeout(timeoutId)

      const elapsed = Date.now() - startTime
      log.info(`[Umi-OCR] OCR 识别完成，耗时: ${elapsed}ms`)

      if (!response.ok) {
        return {
          success: false,
          error: `服务错误: ${response.status} ${response.statusText}`,
        }
      }

      // 解析响应
      const data = await response.json() as any
      
      if (data.code === 100 || data.code === 101) {
        // code 100: 成功，data 是识别结果列表
        // code 101: 成功但无文字
        const results = data.data || []
        
        if (results.length === 0) {
          log.info('[Umi-OCR] 未识别到任何文字')
          return {
            success: true,
            text: '',
            details: data,
          }
        }

        // 提取所有文本行
        const textLines = results.map((item: any) => item.text || '').filter((t: string) => t)
        const fullText = textLines.join('\n')

        log.info(`[Umi-OCR] 识别到 ${textLines.length} 行文本`)
        log.debug('[Umi-OCR] 识别结果:', fullText)

        return {
          success: true,
          text: fullText,
          details: data,
        }
      } else {
        // 识别失败
        log.error('[Umi-OCR] OCR 识别失败:', data)
        return {
          success: false,
          error: data.message || data.data || '识别失败',
          details: data,
        }
      }
    } catch (error: any) {
      log.error('[Umi-OCR] OCR 识别异常:', error)
      
      let errorMessage = '识别失败'
      if (error.name === 'AbortError') {
        errorMessage = 'Umi-OCR 服务请求超时'
      } else if (error.code === 'ECONNREFUSED') {
        errorMessage = 'Umi-OCR 服务连接失败，请确保服务已启动'
      } else {
        errorMessage = error.message || '识别失败'
      }

      return {
        success: false,
        error: errorMessage,
      }
    }
  }

  /**
   * 更新配置
   */
  updateConfig(config: {
    apiUrl?: string
    language?: string
    timeout?: number
  }) {
    if (config.apiUrl) {
      this.apiUrl = config.apiUrl.replace(/\/$/, '')
    }
    if (config.language) {
      this.language = config.language
    }
    if (config.timeout) {
      this.timeout = config.timeout
    }

    log.info('[Umi-OCR] 配置已更新', {
      apiUrl: this.apiUrl,
      language: this.language,
      timeout: this.timeout,
    })
  }
}

// 全局实例
let umiOCRServiceInstance: UmiOCRService | null = null

/**
 * 初始化 Umi-OCR 服务
 */
export function initUmiOCRService(config: {
  apiUrl: string
  language?: string
  timeout?: number
}): UmiOCRService {
  umiOCRServiceInstance = new UmiOCRService(config)
  return umiOCRServiceInstance
}

/**
 * 获取 Umi-OCR 服务实例
 */
export function getUmiOCRService(): UmiOCRService | null {
  return umiOCRServiceInstance
}

/**
 * 销毁 Umi-OCR 服务
 */
export function destroyUmiOCRService(): void {
  if (umiOCRServiceInstance) {
    log.info('[Umi-OCR] 服务已销毁')
    umiOCRServiceInstance = null
  }
}

